#include"util.hpp"
#include"level.hpp"
#include"message.hpp"
#include"formatter.hpp"
#include"sink.hpp"
#include <unistd.h> 
#include"logger.hpp"
#include"buffer.hpp"
#include"looper.hpp"
#include"dhylog.hpp"
enum class TimeGap
{
    GAP_SECOND,
    GAP_MINUTE,
    GAP_HOUR,
    GAP_DAY,
};

class LogSink
{
public:
    using ptr = std::shared_ptr<LogSink>;
    LogSink() {}
    virtual void log(const char *data, size_t len) = 0;
};

class RollByTimeSink : public LogSink
{
public:
    using ptr = std::shared_ptr<RollByTimeSink>;

    RollByTimeSink(const std::string &basename, TimeGap gap_type) : _basename(basename)
    {
        switch (gap_type)
        {
        case TimeGap::GAP_SECOND:
            _gap_size = 1;
            break;
        case TimeGap::GAP_MINUTE:
            _gap_size = 60;
            break;
        case TimeGap::GAP_HOUR:
            _gap_size = 6060;
            break;
        case TimeGap::GAP_DAY:
            _gap_size = 360024;
            break;
        }

        _cur_gap = _gap_size==1?dhylog::util::date::now():dhylog::util::date::now() % _gap_size; //获取当前时间段
        std::string filename = createFilename();
        dhylog::util::File::create_directory(dhylog::util::File::path(filename));
        _ofs.open(filename, std::ios::binary | std::ios::app);
        assert(_ofs.is_open());
    }

    void log(const char *data, size_t len) override
    {
        time_t cur = dhylog::util::date::now();
        if ((cur % _gap_size) != _cur_gap)
        {
            _ofs.close();
            std::string filename = createFilename();
            _ofs.open(filename, std::ios::binary | std::ios::app);
            assert(_ofs.is_open());
        }
        _ofs.write(data, len);
        if (_ofs.good() == false)
        {
            std::cout << "日志文件输出失败" << std::endl;
        }
    }

private:
    std::string createFilename()
    {
        time_t t = dhylog::util::date::now();
        struct tm lt;
        localtime_r(&t, &lt);
        std::stringstream ss;
        ss << _basename;
        ss << lt.tm_year + 1900;
        ss << "-";
        ss << lt.tm_mon + 1;
        ss << "-";
        ss << lt.tm_mday;
        ss << "-";
        ss << lt.tm_hour;
        ss << "-";
        ss << lt.tm_min;
        ss << "-";
        ss << lt.tm_sec;
        ss << ".log";
        return ss.str();
    }

private:
    std::string _basename;
    std::ofstream _ofs;
    size_t _cur_gap; //当前时间段
    size_t _gap_size; //时间段大小
};
void test_log()
{
    // dhylog::Logger::ptr logger=dhylog::LoggerManager::getInstance().getLogger("async_logger");
    // logger->debug( "%s", "测试日志");
    // logger->info( "%s", "测试日志");
    // logger->error("%s", "测试日志");
    // logger->warn( "%s", "测试日志");
    // logger->fatal("%s", "测试日志");
    // size_t cursize=0,count=0;
    // std::string str="测试日志-";
    // while(count<500000)
    // { 
    //     logger->fatal("测试日志-%d\n",count++);
    // }
    DEBUG("%s", "测试日志");
    INFO( "%s", "测试日志");
    ERROR("%s", "测试日志");
    WARN( "%s", "测试日志");
    FATAL("%s", "测试日志");
    size_t cursize=0,count=0;
    std::string str="测试日志-";
    while(count<500000)
    { 
        FATAL("测试日志-%d\n",count++);
    }

}

int main()
{
    // //读取文件，一点一点写入缓冲区，最终将缓冲区数据写入文件，判断生成的新文件和源文件是否一致
    // std::ifstream ifs("./logfile/sync.log",std::ios::binary);
    // if(ifs.is_open()==false){return -1;}//读写位置跳转到文件末尾
    // ifs.seekg(0,std::ios::end);//读写位置跳转到文件末尾
    // size_t fsize=ifs.tellg();//获取当前读写位置相对于起始位置的偏移量
    // ifs.seekg(0,std::ios::beg);//重新跳转到起始位置
    // std::string body;
    // body.resize(fsize);

    // ifs.read(&body[0],fsize);
    // if(ifs.good()==false){std::cout<<"read error\n";return -1;}
    // ifs.close();

    // dhylog::Buffer buffer;
    // for(int i=0;i<body.size();i++)
    // {
    //     buffer.push(&body[i],1);
    // }
    // std::ofstream ofs("./logfile/tmp.log",std::ios::binary);
    // size_t rsize=buffer.readAbleSize();
    // for(int i=0;i<rsize;i++)
    // {
    //     ofs.write(buffer.begin(),1);
    //     buffer.moveReader(1);
    // }
    // ofs.close();


    // std::string logger_name="sync_logger";
    // dhylog::loglevel::value limit=dhylog::loglevel::value::WARN;
    // dhylog::Formatter::ptr fmt(new dhylog::Formatter("[%d{%H:%M:%S}][%p][%c][%f:%l] %m%n"));
    // dhylog::LogSink::ptr stdout_lsp=dhylog::SinkFactory::create<dhylog::StdoutSink>();
    // dhylog::LogSink::ptr file_lsp=dhylog::SinkFactory::create<dhylog::FileSink>("./logfiles/test.log");
    // dhylog::LogSink::ptr roll_lsp=dhylog::SinkFactory::create<dhylog::RollSink>("./logfiles/rot-",1024*1024);
    // std::vector<dhylog::LogSink::ptr> sinks={stdout_lsp,file_lsp,roll_lsp};
    // dhylog::Logger::ptr logger(new dhylog::SyncLogger(logger_name,limit,fmt,sinks));

    // std::unique_ptr<dhylog::LoggerBuilder> builder(new dhylog::LocalLoggerBuilder());
    // builder->buildLoggerName("sync_logger");
    // builder->buildLoggerLevel(dhylog::loglevel::value::WARN);
    // builder->buildFormatter("%m%n");
    // builder->buildLoggerType(dhylog::LoggerType::LOGGER_SYNC);
    // builder->buildSink<dhylog::FileSink>("./logfile/sync.log");
    // builder->buildSink<dhylog::StdoutSink>();
    // dhylog::Logger::ptr logger=builder->build();


    

    std::unique_ptr<dhylog::LoggerBuilder> builder(new dhylog::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildLoggerLevel(dhylog::loglevel::value::WARN);
    builder->buildFormatter("[%c][%f:%l]%m%n");
    builder->buildLoggerType(dhylog::LoggerType::LOGGER_ASYNC);
    //builder->buildEnableUnSafeAsync();
    builder->buildSink<dhylog::FileSink>("./logfile/async.log");
    builder->buildSink<dhylog::StdoutSink>();
    builder->build();
    test_log();
    
    // logger->debug(__FILE__, __LINE__, "%s", "测试日志");
    // logger->info(__FILE__, __LINE__, "%s", "测试日志");
    // logger->error(__FILE__, __LINE__, "%s", "测试日志");
    // logger->warn(__FILE__, __LINE__, "%s", "测试日志");
    // logger->fatal(__FILE__, __LINE__, "%s", "测试日志");
    // size_t cursize=0,count=0;
    // std::string str="测试日志-";
    // while(count<500000)
    // { 
    //     logger->fatal(__FILE__,__LINE__,"测试日志-%d",count++);
    // }
    

    // while(cursize<10*1024*1024)
    // {
    //     std::string tmp=str+std::to_string(count++);
    //     logger->fatal(__FILE__,__LINE__,"测试日志-%d",count++);
    //     cursize+=20;
    // }
    

    // std::string logger_name="sync_logger";
    // dhylog::loglevel::value limit=dhylog::loglevel::value::WARN;
    // dhylog::Formatter::ptr fmt(new dhylog::Formatter("[%d{%H:%M:%S}][%c][%f:%l][%p]%T%m%n"));
    // dhylog::logger::ptr stdout_lsp=dhylog::SinkFactory::creat<dhylog::StdoutSink>();
    // std::cout<<dhylog::util::date::now()<<std::endl;
    // std::string pathname("abc/bcd/efg/a.txt");
    // dhylog::util::File::create_directory(dhylog::util::File::path(pathname));
    // return 0;
    //std::cout<<dhylog::loglevel::toString(dhylog::loglevel::value::D EBUG)<<std::endl;
    // dhylog::LogMsg msg(dhylog::loglevel::value::INFO,53,"main.c","root","格式化功能测试");
    // dhylog::Formatter fmt;
    // std::string str=fmt.format(msg);
    // dhylog::LogSink::ptr std_lsp=dhylog::SinkFactory::create<dhylog::StdoutSink>();
    // dhylog::LogSink::ptr file_lsp=dhylog::SinkFactory::create<dhylog::FileSink>("./logfiles/test.log");
    // dhylog::LogSink::ptr roll_lsp=dhylog::SinkFactory::create<dhylog::RollSink>("./logfiles/rot-",1024*1024);
    // std_lsp->log(str.c_str(),str.size());
    // file_lsp->log(str.c_str(),str.size());
    // size_t cur_fsize=0;
    // size_t count=0;
    // while(cur_fsize<10*1024*1024)
    // {
    //     std::string tmp=str+std::to_string(count++);
    //     roll_lsp->log(tmp.c_str(),tmp.size());
    //     cur_fsize+=tmp.size();
    // }


}
